import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DataSource } from 'typeorm';
import { Order, OrderStatus } from './entities/order.entity';
import { OrderItem } from './entities/order-item.entity';
import { CreateOrderDto } from './dto/create-order.dto';
import { UpdateOrderDto } from './dto/update-order.dto';
import { Book } from '../book/entities/book.entity';
import { User } from '../user/entities/user.entity';

@Injectable()
export class OrderService {
  constructor(
    @InjectRepository(Order)
    private orderRepository: Repository<Order>,
    @InjectRepository(OrderItem)
    private orderItemRepository: Repository<OrderItem>,
    @InjectRepository(Book)
    private bookRepository: Repository<Book>,
    @InjectRepository(User)
    private userRepository: Repository<User>,
    private dataSource: DataSource,
  ) {}

  async create(createOrderDto: CreateOrderDto, userId: string) {
    // 检查用户是否存在
    const user = await this.userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw new NotFoundException(`ID为${userId}的用户不存在`);
    }

    // 开始事务
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 生成订单编号
      const orderNumber = `ORD${Date.now()}${Math.floor(Math.random() * 1000)}`;

      // 创建订单
      const order = this.orderRepository.create({
        order_number: orderNumber,
        user_id: userId,
        shipping_address: createOrderDto.shipping_address,
        phone: createOrderDto.phone,
        note: createOrderDto.note,
        total_amount: 0, // 初始化总金额为0
        status: OrderStatus.PENDING,
      });

      // 保存订单
      const savedOrder = await this.orderRepository.save(order);

      // 处理订单项
      let totalAmount = 0;
      const orderItems: OrderItem[] = [];

      for (const item of createOrderDto.items) {
        // 检查图书是否存在
        const book = await this.bookRepository.findOne({ where: { id: item.book_id } });
        if (!book) {
          throw new NotFoundException(`ID为${item.book_id}的图书不存在`);
        }

        // 检查库存
        if (book.stock < item.quantity) {
          throw new BadRequestException(`图书《${book.title}》库存不足`);
        }

        // 计算小计金额
        const subtotal = book.price * item.quantity;
        totalAmount += subtotal;

        // 创建订单项
        const orderItem = this.orderItemRepository.create({
          order_id: savedOrder.id,
          book_id: book.id,
          quantity: item.quantity,
          price: book.price,
          subtotal,
        });

        orderItems.push(orderItem);

        // 更新图书库存
        book.stock -= item.quantity;
        await this.bookRepository.save(book);
      }

      // 保存订单项
      await this.orderItemRepository.save(orderItems);

      // 更新订单总金额
      savedOrder.total_amount = totalAmount;
      await this.orderRepository.save(savedOrder);

      // 提交事务
      await queryRunner.commitTransaction();

      // 返回完整订单信息
      return this.findOne(savedOrder.id);
    } catch (error) {
      // 回滚事务
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      // 释放查询运行器
      await queryRunner.release();
    }
  }

  async findAll() {
    return this.orderRepository.find({
      relations: ['items', 'items.book', 'user'],
      order: { created_at: 'DESC' },
    });
  }

  async findAllByUser(userId: string) {
    // 检查用户是否存在
    const user = await this.userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw new NotFoundException(`ID为${userId}的用户不存在`);
    }

    return this.orderRepository.find({
      where: { user_id: userId },
      relations: ['items', 'items.book'],
      order: { created_at: 'DESC' },
    });
  }

  async findOne(id: string) {
    const order = await this.orderRepository.findOne({
      where: { id },
      relations: ['items', 'items.book', 'user'],
    });

    if (!order) {
      throw new NotFoundException(`ID为${id}的订单不存在`);
    }

    return order;
  }

  async update(id: string, updateOrderDto: UpdateOrderDto) {
    const order = await this.orderRepository.findOne({ where: { id } });
    if (!order) {
      throw new NotFoundException(`ID为${id}的订单不存在`);
    }

    // 更新订单
    Object.assign(order, updateOrderDto);
    return this.orderRepository.save(order);
  }

  async remove(id: string) {
    const order = await this.orderRepository.findOne({
      where: { id },
      relations: ['items'],
    });

    if (!order) {
      throw new NotFoundException(`ID为${id}的订单不存在`);
    }

    // 开始事务
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 如果订单状态是待付款，恢复图书库存
      if (order.status === OrderStatus.PENDING) {
        for (const item of order.items) {
          const book = await this.bookRepository.findOne({ where: { id: item.book_id } });
          if (book) {
            book.stock += item.quantity;
            await this.bookRepository.save(book);
          }
        }
      }

      // 删除订单项
      await this.orderItemRepository.remove(order.items);

      // 删除订单
      await this.orderRepository.remove(order);

      // 提交事务
      await queryRunner.commitTransaction();

      return { message: '订单删除成功' };
    } catch (error) {
      // 回滚事务
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      // 释放查询运行器
      await queryRunner.release();
    }
  }

  async addSampleOrders(userId: string) {
    // 检查用户是否存在
    const user = await this.userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw new NotFoundException(`ID为${userId}的用户不存在`);
    }

    // 获取所有图书
    const books = await this.bookRepository.find({ take: 3 });
    if (books.length === 0) {
      throw new NotFoundException('没有找到图书，请先添加图书');
    }

    // 创建示例订单
    const createOrderDto: CreateOrderDto = {
      shipping_address: '北京市海淀区中关村大街1号',
      phone: '13800138000',
      note: '示例订单',
      items: books.map(book => ({
        book_id: book.id,
        quantity: 1,
      })),
    };

    return this.create(createOrderDto, userId);
  }
}
